# Deploy and production readiness

> Deploy a configured Supacharger application to Vercel, connect it to hosted Supabase, and complete operational checks before public launch.

# Deploy and production readiness

Complete the [hosted setup wizard](../guides/setup-wizard.md) first. It establishes the hosted Supabase project, Vercel deployment, Auth URLs and policy, SMTP, templates, and end-to-end authentication checks. This page covers the Vercel deployment sequence and the broader application review before opening the product to real users.

## Vercel deployment sequence

1. Connect the repository to the intended Vercel team and project.
2. Select the production branch and verify the framework and root-directory settings.
3. Add environment variables for Development, Preview, and Production.
4. Produce an initial deployment and attach the canonical production domain.
5. Set `NEXT_PUBLIC_SITE_URL` to that HTTPS origin and redeploy.
6. Configure the same origin as Supabase Auth's Site URL.
7. Add exact allowed redirects for callbacks, confirmations, and password recovery.
8. Complete the wizard's production authentication tests.

See [Configure environment variables](../guides/hosted-setup/03-environment-variables.md) and [Deploy and establish URLs](../guides/hosted-setup/04-deploy-and-urls.md) for the actual values and verification checklist.

## Preview deployments

Choose deliberately whether previews use production or a separate staging Supabase project. A staging project is preferable when branches are untrusted or preview activity must not modify production data.

If preview authentication is enabled against a project, add only the required Vercel preview pattern to that project's redirect allow-list. Do not make the production Site URL a preview URL.

## Redeployment rule

Vercel environment-variable changes do not alter a deployment that has already been built. Redeploy after adding or changing build-time or runtime configuration, then confirm the new deployment is the one serving the production domain.

## Database access

- Enable RLS on every table exposed through the Data API.
- Confirm policies authorize the intended owner, organization, or role rather than merely checking `TO authenticated`.
- Remember that an `UPDATE` operation also needs a matching `SELECT` policy and should normally use both `USING` and `WITH CHECK`.
- Review grants independently from RLS. A role must be able to reach an exposed object before RLS can filter its rows.
- Keep internal data in an unexposed schema and expose narrowly scoped functions or views where needed.
- Use `security_invoker = true` for Postgres 15+ views that must obey the caller's RLS.
- Review every `SECURITY DEFINER` function, keep genuinely privileged functions out of exposed schemas, restrict `EXECUTE`, and validate the caller inside the function.

Run Supabase's database and security advisors and resolve each finding according to the application's access model. Never disable RLS or add broad grants simply to remove a warning.

## Keys and environment isolation

- Use a publishable key in the browser.
- Keep Supabase secret or legacy service-role keys server-only.
- Confirm no Stripe secret, webhook secret, SMTP credential, or database password uses a `NEXT_PUBLIC_` variable.
- Use separate hosted projects and secrets for staging and production.
- Rotate any credential that has appeared in Git history, a client bundle, build output, or public logs.
- Restrict who can read or change production environment variables in Vercel and Supabase.

## Authentication and abuse

- Keep email confirmation enabled when the product requires verified addresses.
- Set a reasonable Email OTP Expiration and compatible resend cooldown.
- Use custom SMTP with SPF, DKIM, and DMARC.
- Add CAPTCHA or Turnstile to public email-triggering actions when automated abuse is plausible.
- Protect Supabase organization accounts with MFA and maintain more than one appropriate owner.
- Enable only the Auth providers and account-change flows the application actually supports.

## Edge Functions and webhooks

- Restrict CORS to the intended origins; do not ship a permissive wildcard with credentials.
- Validate webhook signatures before parsing or acting on event data.
- Make event ingestion idempotent and safe to retry.
- Store webhook and reconciliation secrets only in the server environment.
- Bound request bodies, validate inputs, and return safe errors without internal credentials or stack traces.
- Ensure background work is awaited or explicitly handed to the runtime's supported continuation mechanism.

## Application behavior

- Remove sensitive debug logging and confirm production logs do not include tokens, cookies, passwords, full payment payloads, or personal data that is not operationally necessary.
- Verify error, not-found, maintenance, and authentication-failure pages on the production domain.
- Exercise one permitted and one forbidden operation for every important user role.
- Confirm onboarding, organization selection, billing access, and account deletion behave correctly where enabled.
- Test backups and document the restore procedure before relying on them.
- Define monitoring and ownership for Auth, database, Vercel, Stripe, and email-delivery failures.

## Release record

Record the deployed commit, migration version, Supabase and Vercel project identities, enabled Auth methods, important security exceptions, test date, and reviewer. Store identifiers and decisions—not secret values.

Repeat the relevant checks after changing domains, Auth policy, RLS, privileged functions, providers, environment variables, or email infrastructure.

## Final deployment checkup

Run this check after the implementation is reviewed and before declaring an environment ready:

- the consumer lock references a published, reachable Core commit or immutable tag;
- every exact managed path matches that lock and developer-owned CSS, adapters, configuration and catalogues remain intact;
- lint, type checks, Core contract tests, project tests, English catalogue validation and Bruno parity pass;
- the linked migration list contains only reviewed forward migrations, the dry run is understood, and a suitable backup exists;
- hosted migrations have been applied and the ledger is rechecked;
- `app.custom_access_token_hook` is selected under hosted Authentication Hooks and a refreshed test session contains only the expected safe claims;
- hosted Auth URLs, email templates, OTP length, MFA policy, SMTP, Storage policies and secrets match the target environment;
- logout, login, OTP, password reset, account changes, billing recovery and organisation switching have been exercised in the deployed browser; and
- logs and alerting expose failures without recording passwords, tokens or private customer data.

Do not treat checked-in `supabase/config.toml` as proof of a hosted setting. Local and hosted Auth configuration are separate release surfaces.
